﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lxzhu.OpenGL.Core
{
    /// <summary>
    /// 这个是系统里面用到的标准颜色的表示.
    /// 系统还将提供其他颜色体系.同时提供各种颜色体系和标准颜色之间的互相转换.
    /// </summary>
    public  struct Color
    {        
        private const int MMAX = 255;
        private const int AMAX = 100;
        private const int M = 256;
        private const int M2 = 256 * 256;
        private const int M3 = 256 * 256 * 256;
        private const int MA = 101;
        private int mColorCode ;
        public static Color FromRGBA(int code)
        {
            Color ret = new Color();
            ret.mColorCode = code;
            return ret;
        }
        public static Color FromRGBA(int r, int g, int b, int a)
        {
            Color ret = new Color();
            ret.Compute(r, g, b, a);
            return ret;
        }
        public static Color FromRGBA(int r, int g, int b)
        {
            return FromRGBA(r, g, b, 0);
        }
        private void Compute(int r, int g, int b, int a)
        {
            mColorCode = a * 256 + b;
            mColorCode = mColorCode * 256 + g;
            mColorCode = mColorCode * 256 + r;
        }        
        private int Compress(int v, int max)
        {
            if (v < 0) v = 0;
            else if (v > max) v = max;
            return v;
        }
        public int R
        {
            get
            {
                return mColorCode % M;
            }
            set
            {
                value = Compress(value, MMAX);
                Compute(value, this.G, this.B, this.A);
            }
        }
        public int G
        {
            get
            {
                return (mColorCode/M) % M;
            }
            set
            {
                value = Compress(value, MMAX);
                    Compute(this.R, value, this.B, this.A);
            }
        }
        public int B
        {
            get
            {
                return (mColorCode/M2) % M;
            }
            set
            {
                value = Compress(value, MMAX);
                    Compute(this.R, this.G, value, this.A);
            }
        }
        public int A
        {
            get
            {
                return (mColorCode/M3) % MA;
            }
            set
            {
                value = Compress(value, AMAX);
                Compute(this.R, this.G, this.B, value);
            }
        }
        public int RGBA
        {
            get
            {
                return mColorCode;
            }
            set
            {

                value = Compress(value, Int32.MaxValue);
                mColorCode = value;
            }
        }
        public override int GetHashCode()
        {
            return this.mColorCode;
        }
        #region 归一化到[0.0,1.0]之间的数字
        public float NormalR
        {
            get
            {
                return this.R /(float)MMAX;
            }
            set
            {
                this.R = (int)(MMAX * value);
            }
        }
        public float NormalG
        {
            get
            {
                return this.G / (float)MMAX;
            }
            set
            {
                this.G = (int)(MMAX * value);
            }
        }
        public float NormalB
        {
            get
            {
                return this.B / (float)MMAX;
            }
            set
            {
                this.B = (int)(MMAX * value);
            }
        }
        public float NormalA
        {
            get
            {
                return this.A / (float)AMAX;
            }
            set
            {
                this.A = (int)(AMAX * value);
            }
        }
        public float[] Normal3V
        {
            get
            {
                return new float[3] { this.NormalR,this.NormalG,this.NormalB};
            }
            set
            {
                if (value != null && value.Length >= 3)
                {
                    this.NormalR = value[0];
                    this.NormalG = value[1];
                    this.NormalB = value[2];
                    this.NormalA = 0;
                }
            }
        }
        public float[] Normal4V
        {
            get
            {
                return new float[4] { this.NormalR, this.NormalG, this.NormalB, this.NormalA };
            }
            set
            {
                if (value != null && value.Length >= 4)
                {
                    this.NormalR = value[0];
                    this.NormalG = value[1];
                    this.NormalB = value[2];
                    this.NormalA = value[3];
                }
            }
        }
        #endregion
    }
}
